<template>
    <div class="page-wrap" ref="wrap">
        <vxe-grid
            ref="table"
            border
            resizable
            highlight-hover-row
            show-overflow
            header-cell-class-name="page-table-header-cell"
            :height="height"
            :loading="loading"
            :checkbox-config="{trigger: 'row', highlight: true, range: true}"
            :sort-config="{showIcon: false}"
            :data="dataSource"
            :context-menu="{body: {options: buttons}, visibleMethod}"
            :columns="fixedColumns"
            :pager-config="{ 
                border: true,
                background: true,
                size: 'small',
                align: 'center',
                pageSizes: [20, 50, 100, 200, 500],
                layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'], 
                ...pageInfo
            }"
            @cell-context-menu="cellContextMenuEvent"
            @context-menu-click="contextMenuClickEvent"
            @checkbox-change="selectChangeEvent"
            @page-change="handlePageChange"
        />
    </div>
</template>

<script>
import TextFilter from '../qtHeaderCell/textFilter';
import TimeFilter from '../qtHeaderCell/timeFilter';
import SelectFilter from '../qtHeaderCell/selectFilter';
import { operatorList } from '../qtHeaderCell/operatorList';

export default {
    name: 'qtPageTable',

    data() {
        return {
            loading: false,
            dataSource: [],
            height: 'auto',
            selections: [],
            pageInfo: {
                total: 0,
                currentPage: 1,
                pageSize: 20
            },
            queryModel: {}
        };
    },

    props: {
        buttons: {
            type: Array,
            default() {
                return [];
            }
        },
        columns: {
            type: Array,
            default() {
                return [];
            }
        },
        fetchApi: {
            type: String
        },
        fetchParams: {
            type: Object,
            default() {
                return {};
            }
        }
    },

    provide() {
        return {
            $pageTable: this
        };
    },

    computed: {
        fixedColumns() {
            const columns = this._.cloneDeep(this.columns);

            return columns.map(item => {
                item.slots = {};
                item.sortable = true;

                this.setQuerModel(item);

                if (item.router) {
                    const { field, callback } = item.router;

                    Object.assign(item.slots, {
                        default: ({ row }) => {
                            return [
                                <a
                                    class="am-text-secondary"
                                    href="javascript:;"
                                    onClick={() => {
                                        callback(row);
                                    }}
                                >
                                    {row[field]}
                                </a>
                            ];
                        }
                    });
                }

                if (item.headerFilter) {
                    let $el = {};

                    switch (item.headerFilter) {
                        case 'textFilter':
                            $el = {
                                header: ({ column }) => {
                                    return [
                                        <TextFilter
                                            column={column}
                                            queryModel={this.queryModel}
                                            onSearch={() => {
                                                this.searchChange();
                                            }}
                                        />
                                    ];
                                }
                            };
                            break;

                        case 'timeFilter':
                            $el = {
                                header: ({ column }) => {
                                    return [
                                        <TimeFilter
                                            column={column}
                                            queryModel={this.queryModel}
                                            onSearch={() => {
                                                this.searchChange();
                                            }}
                                        />
                                    ];
                                }
                            };
                            break;

                        case 'selectFilter':
                            $el = {
                                header: ({ column }) => {
                                    return [
                                        <SelectFilter
                                            column={column}
                                            queryModel={this.queryModel}
                                            options={item.filterOptions ? item.filterOptions : null}
                                            onSearch={() => {
                                                this.searchChange();
                                            }}
                                        />
                                    ];
                                }
                            };
                            break;
                    }

                    Object.assign(item.slots, $el);
                }

                return item;
            });
        }
    },

    created() {
        this.fetchList();
    },

    activated() {
        this.$refs.table.clearCheckboxRow();

        if (this.$refs.wrap.offsetHeight - 50 !== this.height) {
            this.initHeight();
        }
    },

    mounted() {
        this.initHeight();

        window.addEventListener(
            'resize',
            this._.throttle(this.initHeight, 500, {
                leading: true,
                trailing: true
            }),
            false
        );
    },

    destroyed() {
        window.removeEventListener('resize', this.initHeight, false);
    },

    methods: {
        setQuerModel(item) {
            switch (item.headerFilter) {
                case 'textFilter':
                    this.$set(this.queryModel, item.field, {
                        filterOperator: '=',
                        filterValue: ''
                    });
                    break;

                case 'selectFilter':
                    this.$set(this.queryModel, item.field, {
                        filterOperator: '=',
                        filterValue: []
                    });
                    break;

                case 'timeFilter':
                    this.$set(this.queryModel, item.field, {
                        type: 'date',
                        filterValue: []
                    });
                    break;
            }
        },

        refresh() {
            this.fetchList();
        },

        fetchList() {
            this.loading = true;

            setTimeout(() => {
                let list = [];

                for (var index = 0; index < 120; index++) {
                    list.push({
                        id: index + 10000,
                        name: 'test' + index,
                        role: 'developer',
                        sex: 'Man',
                        date: '2019-05-01',
                        time: 1556677810888 + index * 500,
                        region: 'ShenZhen',
                        address: 'address abc' + index
                    });
                }

                this.pageInfo.total = list.length;
                this.dataSource = list;
                this.loading = false;
            }, 500);
        },

        initHeight() {
            this.$nextTick(() => {
                const getHeight = () => {
                    return new Promise(resolve => {
                        if (this.$refs.wrap) {
                            resolve(this.$refs.wrap.offsetHeight - 50);
                        }
                    });
                };
                getHeight().then(value => {
                    this.height = value;
                });
            });
        },

        cellContextMenuEvent({ row }) {
            this.$refs.table.setCurrentRow(row);
        },

        contextMenuClickEvent({ menu }) {
            if (this._.isFunction(menu.callback)) {
                menu.callback();
            }
        },

        selectChangeEvent({ selection }) {
            this.selections = selection;
            this.$emit('selection', selection);
        },

        visibleMethod({ options, rowIndex }) {
            this.$refs.table.setCheckboxRow([this.dataSource[rowIndex]], true);
            this.selections = this.$refs.table.getCheckboxRecords();
            this.$emit('selection', this.selections);

            const { length } = this.selections;

            options.forEach(list => {
                list.forEach(item => {
                    if (item.type === 'single') {
                        item.disabled = length > 1;
                    }

                    if (item.children) {
                        item.children.forEach(itemChild => {
                            if (itemChild.type === 'single') {
                                itemChild.disabled = length > 1;
                            }
                        });
                    }
                });
            });

            return true;
        },

        handlePageChange({ currentPage, pageSize }) {
            this.pageInfo.currentPage = currentPage;
            this.pageInfo.pageSize = pageSize;

            this.fetchList();
        },

        searchChange() {
            const tmpObj = this._.cloneDeep(this.queryModel);
            const items = [];

            for (let i in tmpObj) {
                const obj = tmpObj[i];

                if (Array.isArray(obj.filterValue) && obj.filterValue.length > 0) {
                    if (obj.type === 'date') {
                        obj.filterValue.forEach((time, index) => {
                            set(i, time, ['GreaterThanOrEqual', 'LessThanOrEqual'][index], 2);
                        });
                    }
                }

                if (typeof obj.filterValue == 'string' && obj.filterValue !== '') {
                    set(i, obj.filterValue, obj.filterOperator);
                }
            }

            function set(key, value, operator, type = 1) {
                let groupObj = {};

                Reflect.set(groupObj, 'Field', key);
                Reflect.set(
                    groupObj,
                    'Method',
                    type === 1
                        ? operatorList.find(item => {
                              return item.value === operator;
                          }).method
                        : operator
                );
                Reflect.set(groupObj, 'Value', value);

                items.push(groupObj);
                groupObj = {};
            }

            console.log(items);

            this.refresh();
        }
    }
};
</script>

<style lang="scss" scoped>
.page-wrap {
    position: relative;
    height: 100%;
    ::v-deep .vxe-pager {
        .vxe-input--inner {
            border: 1px solid #a0a2a9;
        }
    }
    ::v-deep .page-table-header-cell {
        background: #f5f5f5;
        padding: 4px 0 !important;
    }
}
</style>
    